<template>
  <div class="store-page page-view">
    <!-- 面包屑导航 -->
    <div class="breadcrumb">
      <div class="list">
        <div class="home-icon">
          <i class="iconfont icon-home"></i>
        </div>
        <div class="item">
          <router-link to="/">
            <span class="text">首页</span>
          </router-link>
        </div>
        <div class="seperate">
          <i class="iconfont icon-arrow-right-thin"></i>
        </div>
        <div class="item">
          <span class="text">门店管理</span>
        </div>
      </div>
      <h1 class="page-title">门店管理</h1>
    </div>

    <!-- 操作栏 -->
    <div class="action-bar">
      <router-link to="/store/add" class="v-button primary">
        <i class="iconfont icon-add"></i> 添加门店
      </router-link>

      <!-- 新增导入按钮 -->
      <button class="v-button primary" @click="showImportDialog = true">
        <i class="iconfont icon-copy"></i> 批量导入
      </button>

      <!-- 搜索框 -->
      <div class="search-wrapper">
        <div class="search-input">
          <i class="iconfont icon-search"></i>
          <input
            v-model="searchQuery"
            placeholder="搜索门店名称/联系人"
            @keyup.enter="handleSearch"
          />
          <i
            v-if="searchQuery"
            class="iconfont icon-close"
            @click="handleSearchClear"
          ></i>
        </div>
      </div>
    </div>

    <!-- 筛选条件 -->
    <div class="filter-bar">
      <div class="filter-group">
        <label class="filter-label">所在地区</label>
        <BaseSelect
          v-model="filters.province.code"
          :options="provinceOptions"
          placeholder="请选择省"
          @change="
            (val) => {
              filters.province.name =
                provinceOptions.find((p) => p.value === val)?.text || '';
              handleProvinceChange();
            }
          "
        />
        <BaseSelect
          v-model="filters.city.code"
          :options="cityOptions"
          placeholder="请选择市"
          @change="
            (val) => {
              filters.city.name =
                cityOptions.find((c) => c.value === val)?.text || '';
              handleCityChange();
            }
          "
          :disabled="!filters.province.code"
        />
        <BaseSelect
          v-model="filters.district.code"
          :options="districtOptions"
          placeholder="请选择区县"
          @change="
            (val) => {
              filters.district.name =
                districtOptions.find((d) => d.value === val)?.text || '';
            }
          "
          :disabled="!filters.city.code"
        />
      </div>

      <button class="v-button primary" @click="applyFilters">
        <i class="iconfont icon-filter-records"></i> 筛选
      </button>
      <button class="v-button outline" @click="resetFilters">
        <i class="iconfont icon-reset"></i> 重置
      </button>
    </div>

    <!-- 门店表格 -->
    <div class="v-container">
      <table class="v-table">
        <thead>
          <tr>
            <th width="80">ID</th>
            <th>门店编码</th>
            <th>门店名称</th>
            <th>联系人</th>
            <th>联系电话</th>
            <th>所在地区</th>
            <th>门店级别</th>
            <th width="180">创建时间</th>
            <th width="180">更新时间</th>
            <th width="170">操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="store in storeList" :key="store.id">
            <td>{{ store.id }}</td>
            <td>{{ store.store_code || "-" }}</td>
            <td>{{ store.name }}</td>
            <td>{{ store.contact_person || "-" }}</td>
            <td>{{ store.contact_phone || "-" }}</td>
            <td>{{ formatArea(store) }}</td>
            <td>{{ formatStoreLevel(store.store_level) }}</td>
            <td>{{ formatTimestamp(store.created_at) }}</td>
            <td>{{ formatTimestamp(store.updated_at) }}</td>
            <td>
              <div class="control">
                <router-link :to="'/store/edit/' + store.id" class="v-button">
                  <i class="iconfont icon-edit"></i> 编辑
                </router-link>
                <button class="v-button danger" @click="confirmDelete(store)">
                  <i class="iconfont icon-delete1"></i> 删除
                </button>
              </div>
            </td>
          </tr>
          <tr v-if="!loading && storeList.length === 0">
            <td colspan="10" class="empty-row">
              <i class="iconfont icon-empty"></i>
              {{ searchQuery ? "没有找到匹配的门店" : "暂无数据" }}
            </td>
          </tr>
        </tbody>
      </table>

      <!-- 分页 -->
      <div class="pagination-wrapper" v-if="pagination.totalPages > 1">
        <div class="v-pagination">
          <button
            class="v-button"
            :disabled="pagination.page === 1"
            @click="handlePageChange(pagination.page - 1)"
          >
            上一页
          </button>

          <template v-for="page in visiblePages" :key="page">
            <button
              class="v-button"
              :class="{ primary: page === pagination.page }"
              @click="handlePageChange(page)"
            >
              {{ page }}
            </button>
          </template>

          <button
            class="v-button"
            :disabled="pagination.page === pagination.totalPages"
            @click="handlePageChange(pagination.page + 1)"
          >
            下一页
          </button>
        </div>

        <div class="page-info">
          共 {{ pagination.total }} 条，当前 {{ pagination.page }}/{{
            pagination.totalPages
          }}
          页
        </div>
      </div>
    </div>

    <!-- 批量导入模态框 -->
    <teleport to="body">
      <div
        v-if="showImportDialog"
        class="modal-overlay"
        @click.self="closeImportDialog"
      >
        <div class="modal-container">
          <div class="modal-header">
            <h3>批量导入门店</h3>
            <button class="modal-close" @click="closeImportDialog">
              <i class="iconfont icon-close"></i>
            </button>
          </div>

          <div class="modal-body">
            <!-- 步骤1：下载模板 -->

            <!-- 步骤2：上传文件 -->
            <div  class="import-step">
              <div class="step-content">
                <div
                  class="upload-area"
                  :class="{ dragover: isDragover, 'has-file': importFile }"
                  @click="triggerFileInput"
                  @dragover.prevent="isDragover = true"
                  @dragleave.prevent="isDragover = false"
                  @drop.prevent="handleFileDrop"
                >
                  <input
                    ref="fileInput"
                    type="file"
                    accept=".csv"
                    @change="handleFileSelect"
                    style="display: none"
                  />

                  <div class="upload-placeholder" v-if="!importFile">
                    <i class="iconfont icon-upload"></i>
                    <p>点击或拖拽CSV文件到此处</p>
                    <p class="upload-tip">支持.csv格式，最大10MB</p>
                  </div>

                  <div class="upload-file-info" v-else>
                    <i class="iconfont icon-file"></i>
                    <div class="file-details">
                      <p class="file-name">{{ importFile.name }}</p>
                      <p class="file-size">
                        {{ formatFileSize(importFile.size) }}
                      </p>
                    </div>
                    <button class="remove-file" @click.stop="removeFile">
                      <i class="iconfont icon-close"></i>
                    </button>
                  </div>
                </div>

                <div class="upload-requirements">
                  <h5>导入要求：</h5>
                  <ul>
                    <li>文件必须为CSV格式</li>
                    <li>
                      表头必须包含：授权编号,门店名称,星级,省份,市,县,详细地址
                    </li>
                    <li>授权编号、门店名称、省份、市、详细地址为必填项</li>
                    <li>星级为0-5之间的数字，默认为0</li>
                  </ul>
                </div>
              </div>
            </div>

            <!-- 步骤3：导入结果 -->
            <div v-if="importStep === 3" class="import-step">
              <div class="step-header">
                <span class="step-number">3</span>
                <h4>导入结果</h4>
              </div>
              <div class="step-content">
                <div
                  class="import-result"
                  :class="importResult.code === 200 ? 'success' : 'error'"
                >
                  <i
                    class="iconfont"
                    :class="
                      importResult.code === 200 ? 'icon-success' : 'icon-error'
                    "
                  ></i>
                  <p class="result-message">{{ importResult.msg }}</p>

                  <div class="result-details" v-if="importResult.data">
                    <p>成功: {{ importResult.data.success }} 条</p>
                    <p>失败: {{ importResult.data.error }} 条</p>

                    <div
                      class="error-list"
                      v-if="
                        importResult.data.errors &&
                        importResult.data.errors.length
                      "
                    >
                      <h6>错误详情：</h6>
                      <ul>
                        <li
                          v-for="(error, index) in importResult.data.errors"
                          :key="index"
                        >
                          {{ error }}
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="modal-footer">
            <button
              class="v-button outline"
              @click="importStep > 1 ? importStep-- : closeImportDialog"
              :disabled="importing"
            >
              上一步
            </button>

            <button
              class="v-button primary"
              @click="handleNextStep"
              :disabled="importing || (importStep === 2 && !importFile)"
              :loading="importing"
            >
              {{ importStep === 3 ? "完成" : "下一步" }}
            </button>
          </div>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import { useRouter } from "vue-router";
import { get, post,upload } from "@/utils/request";
import { formatDate } from "@/utils/date";
import { vConfirm } from "@/plugins/vConfirm";
import { vToast } from "@/plugins/vToast";
import BaseSelect from "@/components/BaseSelect.vue";

const router = useRouter();

// 数据
const storeList = ref([]);
const loading = ref(false);
const searchQuery = ref("");
const areaMap = ref({}); // 存储地区码与名称的映射

// 分页信息
const pagination = ref({
  page: 1,
  pageSize: 10,
  total: 0,
  totalPages: 1,
});

// 门店级别选项
const storeLevelOptions = ref([
  { value: "0", text: "无星级" },
  { value: "1", text: "一星级" },
  { value: "2", text: "三星级" },
  { value: "3", text: "五星级" },
  { value: "4", text: "七星级" },
]);

// 地区数据
const provinceOptions = ref([]);
const cityOptions = ref([]);
const districtOptions = ref([]);

// 筛选条件
const filters = ref({
  province: { code: "", name: "" },
  city: { code: "", name: "" },
  district: { code: "", name: "" },
});

// 导入相关状态
const showImportDialog = ref(false);
const importStep = ref(1);
const isDragover = ref(false);
const importFile = ref(null);
const importing = ref(false);
const importResult = ref({});
const fileInput = ref(null);

// 获取门店列表
const fetchStores = async () => {
  try {
    loading.value = true;

    // 构建查询参数 - 使用省市区名称
    const params = {
      page: pagination.value.page,
      pageSize: pagination.value.pageSize,
      keyword: searchQuery.value,
      province: filters.value.province.name,
      city: filters.value.city.name,
      district: filters.value.district.name,
    };

    const res = await get("/store/list", params);
    if (res.code === 200) {
      storeList.value = res.data.list || [];
      pagination.value = {
        page: res.data.pagination.page || 1,
        pageSize: res.data.pagination.pageSize || 10,
        total: res.data.pagination.total || 0,
        totalPages: res.data.pagination.totalPages || 1,
      };
    } else {
      vToast.error(res.msg || "获取门店列表失败");
    }
  } catch (error) {
    vToast.error("获取门店列表失败");
    console.error(error);
  } finally {
    loading.value = false;
  }
};

// 获取地区数据
const fetchAreas = async (type, parentCode = "") => {
  try {
    const params = { type };
    if (parentCode) params.code = parentCode;

    const res = await get("/city/list", params);

    if (res.code === 200) {
      return res.data.map((item) => ({
        code: item.code,
        name: item.name,
        type: item.type,
      }));
    }
    return [];
  } catch (error) {
    console.error("获取地区数据失败", error);
    return [];
  }
};

// 加载省份数据
const loadProvinces = async () => {
  const provinces = await fetchAreas("province");
  provinceOptions.value = provinces.map((p) => ({
    value: p.code,
    text: p.name,
  }));
};

// 省份变化时加载城市
const handleProvinceChange = async () => {
  filters.value.city = { code: "", name: "" };
  filters.value.district = { code: "", name: "" };
  if (filters.value.province.code) {
    const cities = await fetchAreas("city", filters.value.province.code);
    cityOptions.value = cities.map((c) => ({
      value: c.code,
      text: c.name,
    }));
  } else {
    cityOptions.value = [];
  }
  districtOptions.value = [];
};

// 城市变化时加载区县
const handleCityChange = async () => {
  filters.value.district = { code: "", name: "" };
  if (filters.value.city.code) {
    const districts = await fetchAreas("district", filters.value.city.code);
    districtOptions.value = districts.map((d) => ({
      value: d.code,
      text: d.name,
    }));
  } else {
    districtOptions.value = [];
  }
};

// 格式化地区显示
const formatArea = (store) => {
  const parts = [];
  if (store.province) parts.push(store.province);
  if (store.city && store.city !== store.province) parts.push(store.city);
  if (store.district) parts.push(store.district);
  return parts.join(" / ") || "-";
};

// 格式化门店级别
const formatStoreLevel = (level) => {
  const option = storeLevelOptions.value.find((opt) => opt.value === level);
  return option ? option.text : level || "-";
};

// 格式化时间戳
const formatTimestamp = (timestamp) => {
  if (!timestamp) return "-";
  return formatDate(new Date(timestamp * 1000));
};

// 搜索
const handleSearch = () => {
  pagination.value.page = 1;
  fetchStores();
};

const handleSearchClear = () => {
  searchQuery.value = "";
  pagination.value.page = 1;
  fetchStores();
};

// 筛选
const applyFilters = () => {
  pagination.value.page = 1;
  fetchStores();
};

const resetFilters = () => {
  filters.value = {
    province: { code: "", name: "" },
    city: { code: "", name: "" },
    district: { code: "", name: "" },
  };
  searchQuery.value = "";
  pagination.value.page = 1;
  fetchStores();
};

// 分页
const handlePageChange = (page) => {
  if (page < 1 || page > pagination.value.totalPages) return;
  pagination.value.page = page;
  fetchStores();
};

// 计算可见页码
const visiblePages = computed(() => {
  const { page, totalPages } = pagination.value;
  const pages = [];
  const maxVisible = 5;

  if (totalPages <= maxVisible) {
    for (let i = 1; i <= totalPages; i++) {
      pages.push(i);
    }
  } else {
    const half = Math.floor(maxVisible / 2);
    let start = page - half;
    let end = page + half;

    if (start < 1) {
      start = 1;
      end = maxVisible;
    }

    if (end > totalPages) {
      end = totalPages;
      start = end - maxVisible + 1;
    }

    for (let i = start; i <= end; i++) {
      pages.push(i);
    }
  }

  return pages;
});

// 删除确认
const confirmDelete = (store) => {
  vConfirm({
    message: `确定要删除门店【${store.name}】吗？`,
    onConfirm: () => deleteStore(store.id),
  });
};

const deleteStore = async (id) => {
  try {
    const res = await post("/store/delete", { id });

    if (res.code === 200) {
      vToast.success("门店删除成功");
      fetchStores();
    } else {
      vToast.error(res.msg || "删除失败");
    }
  } catch (error) {
    vToast.error("删除失败");
    console.error(error);
  }
};

// 导入相关方法
const downloadTemplate = () => {
  const templateContent = `授权编号,门店名称,星级,省份,市,县,详细地址
KDX7581713,石柱刘记汽车装饰,0,重庆,重庆市,石柱土家族自治县,石柱土家族自治县红井路59号
KDX7581712,海口龙华膜贴贴汽车装饰行,0,海南省,海口市,龙华区,海口市龙华区南沙路108号膜贴贴汽车贴膜
KDX7581711,雅安市雨城区膜卡车库汽车,,四川省,雅安市,雨城区,四川省雅安市雨城区雅州大道519号`;

  const blob = new Blob([templateContent], { type: "text/csv;charset=utf-8;" });
  const link = document.createElement("a");
  const url = URL.createObjectURL(blob);

  link.setAttribute("href", url);
  link.setAttribute("download", "门店导入模板.csv");
  link.style.visibility = "hidden";

  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);

  // 进入下一步
  importStep.value = 2;
};

const triggerFileInput = () => {
  fileInput.value?.click();
};

const handleFileSelect = (event) => {
  const file = event.target.files[0];
  if (file) {
    validateAndSetFile(file);
  }
};

const handleFileDrop = (event) => {
  isDragover.value = false;
  const files = event.dataTransfer.files;
  if (files.length > 0) {
    validateAndSetFile(files[0]);
  }
};

const validateAndSetFile = (file) => {
  // 验证文件类型
  if (!file.name.toLowerCase().endsWith(".csv")) {
    vToast.error("请选择CSV格式的文件");
    return;
  }

  // 验证文件大小（10MB限制）
  if (file.size > 10 * 1024 * 1024) {
    vToast.error("文件大小不能超过10MB");
    return;
  }

  importFile.value = file;
};

const removeFile = () => {
  importFile.value = null;
  if (fileInput.value) {
    fileInput.value.value = "";
  }
};

const formatFileSize = (bytes) => {
  if (bytes === 0) return "0 Bytes";
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

const handleNextStep = async () => {
  if (importStep.value === 2) {
    await startImport();
  } else if (importStep.value === 3) {
    closeImportDialog();
  } else {
    importStep.value++;
  }
};

const startImport = async () => {
  if (!importFile.value) {
    vToast.error("请选择要导入的文件");
    return;
  }

  importing.value = true;

  try {
    const formData = new FormData();
    formData.append("file", importFile.value);

    const res = await upload("/store/import", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    });

    importResult.value = res;

    if (res.code === 200) {
      vToast.success("导入完成");
      importStep.value = 3;

      // 如果导入成功，刷新门店列表
      if (res.data && res.data.success > 0) {
        fetchStores();
      }
    } else {
      vToast.error(res.msg || "导入失败");
      importStep.value = 3;
    }
  } catch (error) {
    vToast.error("导入失败：" + error.message);
    importResult.value = {
      code: 500,
      msg: error.message,
      data: null,
    };
    importStep.value = 3;
  } finally {
    importing.value = false;
  }
};

const closeImportDialog = () => {
  showImportDialog.value = false;
  setTimeout(() => {
    importStep.value = 1;
    importFile.value = null;
    importResult.value = {};
    if (fileInput.value) {
      fileInput.value.value = "";
    }
  }, 300);
};
onMounted(() => {
  loadProvinces();
  fetchStores();
});

</script>

<style scoped lang="less">
.store-page {
  .breadcrumb {
    margin-bottom: 20px;
  }

  .action-bar {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    gap: 15px;

    .search-wrapper {
      flex: 1;
      max-width: 300px;
      margin-left: auto;

      .search-input {
        position: relative;
        display: flex;
        align-items: center;
        background: var(--v-card-bg);
        border-radius: var(--v-card-radius);
        border: 1px solid var(--v-border-color);
        padding: 0 10px;
        height: 36px;

        i {
          color: var(--v-text-light);
          margin-right: 8px;
        }

        input {
          flex: 1;
          border: none;
          background: transparent;
          outline: none;
          color: var(--v-text);

          &::placeholder {
            color: var(--v-text-light);
          }
        }

        .icon-close {
          cursor: pointer;
          margin-left: 8px;

          &:hover {
            color: var(--v-danger);
          }
        }
      }
    }
  }

  .filter-bar {
    display: flex;
    align-items: center;
    gap: 15px;
    margin-bottom: 20px;
    flex-wrap: wrap;

    .filter-group {
      display: flex;
      align-items: center;
      gap: 8px;

      .filter-label {
        font-size: 14px;
        color: var(--v-text-darker);
        white-space: nowrap;
      }

      .v-select {
        min-width: 120px;
      }
    }
  }

  .v-container {
    background-color: var(--v-card-bg);
    border-radius: var(--v-card-radius);
    box-shadow: var(--v-shadow);
    padding: 20px;
    margin-top: 30px;
    transition: all 0.3s;
  }

  .v-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;

    th,
    td {
      padding: 12px 16px;
      text-align: left;
      border-bottom: 1px solid var(--v-border-color);
    }

    th {
      font-weight: bold;
      color: #333;
    }

    tr:hover {
      background-color: #f9f9f9;
    }
  }

  .control {
    display: flex;
    align-items: center;
    gap: 8px;

    .v-button {
      padding: 0px 8px;
      font-size: 12px;
      min-width: auto;
      height: 32px;
      line-height: 32px;
      background: var(--v-background-pure);
      color: var(--v-sidebar-background);
      border: var(--v-sidebar-background) 1px solid;

      i {
        margin-right: 4px;
      }

      &.danger {
        color: var(--v-danger);
        border-color: var(--v-danger);
      }
    }
  }

  .empty-row {
    text-align: center;
    padding: 20px;
    color: var(--v-text-light);

    .iconfont {
      font-size: 48px;
      margin-bottom: 10px;
      display: block;
    }
  }

  /* 分页样式 */
  .pagination-wrapper {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--v-border-color);

    .v-pagination {
      display: flex;
      gap: 8px;

      .v-button {
        min-width: 36px;
        height: 36px;
        padding: 0 12px;

        &[disabled] {
          opacity: 0.5;
          cursor: not-allowed;
        }
      }
    }

    .page-info {
      color: var(--v-text-light);
      font-size: 14px;
    }
  }

  /* 导入按钮 */
  .v-button.success {
    background: var(--v-success);
    color: white;
    border: none;

    &:hover {
      background: var(--v-success-dark);
    }
  }
}
/* 模态框样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}

.modal-container {
  background: var(--v-card-bg);
  border-radius: var(--v-card-radius);
  box-shadow: var(--v-shadow-lg);
  width: 100%;
  max-width: 600px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  border-bottom: 1px solid var(--v-border-color);

  h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
  }
}

.modal-close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--v-text-light);
  cursor: pointer;
  padding: 5px;

  &:hover {
    color: var(--v-text);
  }
}

.modal-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

.modal-footer {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding: 20px;
  border-top: 1px solid var(--v-border-color);
}

/* 导入步骤样式 */
.import-step {
  margin-bottom: 20px;
}

.step-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 15px;

  .step-number {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--v-primary);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: bold;
  }

  h4 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
  }
}

.step-content {
  padding-left: 34px;
}
/* 导入结果样式 */
.import-result {
  text-align: center;
  padding: 20px;

  .iconfont {
    font-size: 48px;
    margin-bottom: 15px;
    display: block;
  }

  &.success .iconfont {
    color: var(--v-success);
  }

  &.error .iconfont {
    color: var(--v-danger);
  }
}

.result-message {
  font-size: 16px;
  font-weight: 500;
  margin: 0 0 15px 0;
}

.result-details {
  text-align: left;
  background: var(--v-background);
  border-radius: var(--v-card-radius);
  padding: 15px;

  p {
    margin: 0 0 8px 0;
  }
}

.error-list {
  margin-top: 15px;

  h6 {
    margin: 0 0 10px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--v-danger);
  }

  ul {
    margin: 0;
    padding-left: 20px;
    color: var(--v-text-light);

    li {
      margin-bottom: 4px;
      font-size: 13px;
    }
  }
}

/* 加载状态 */
.v-button[loading] {
  position: relative;
  color: transparent !important;

  &::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    border: 2px solid transparent;
    border-top: 2px solid currentColor;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>